package com.shuiyun.jtt.service;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.util.ObjectUtil;
import com.shuiyun.jtt.entity.vo.DeviceInfoVO;
import com.shuiyun.jtt.message.jt808.T0102;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author shuiyun
 * @program gateway
 * @description 设备缓存服务类
 * @date 2022-04-23 13:26
 **/
@Slf4j
@Service
public class DeviceCacheService {
    /** key 设备id
     * 设备缓存 */
    private final Map<Integer, DeviceInfoVO> deviceInfoIdMap = new ConcurrentHashMap<>();
    /**
     * key id
     * value 设备信息
     */
    private final Map<String, DeviceInfoVO> deviceInfoMap = new ConcurrentHashMap<>();

    /**
     * key mobileNO
     * value 在线设备
     */
    private final TimedCache<String, DeviceInfoVO> onlineDeviceInfoMap;

    public DeviceCacheService() {
        // 在线的设备缓存十分钟
        this.onlineDeviceInfoMap = CacheUtil.newTimedCache(10 * DateUtils.MILLIS_PER_MINUTE);
    }

    @PostConstruct
    public void init(){
        // 这里根据业务需求 自行增加设备信息 可以通过查询数据库和调用接口的方式初始化设备信息
        DeviceInfoVO deviceInfoVO = new DeviceInfoVO("18108230998",1,1);
        insert(deviceInfoVO);
    }


    /**
     * 插入缓存
     * @param deviceInfo 设备信息
     * @author shuiyun
     * @date 2022/4/23 15:42
     */
    public void insert(DeviceInfoVO deviceInfo) {
        if (ObjectUtil.isEmpty(deviceInfo.getCardNumber()) || ObjectUtil.isEmpty(deviceInfo.getProtocolVersion())) {
            log.warn("新增设备信息异常 {}", deviceInfo);
        }
        deviceInfoMap.put(deviceInfo.getCardNumber(), deviceInfo);
        deviceInfoIdMap.put(deviceInfo.getId(), deviceInfo);
    }

    /**
     * 根据卡号查找设备信息
     * @param cardNumber 卡号
     * @author shuiyun
     * @date 2022/4/23 16:15
     * @return 设备信息
     */
    public DeviceInfoVO select(String cardNumber) {
        if (ObjectUtil.isEmpty(cardNumber)) {
            return null;
        }
        return deviceInfoMap.get(cardNumber);
    }

    /**
     * 设备认证
     * @param message 认证消息
     * @author shuiyun
     * @date 2022/4/23 16:18
     * @return 认证是否成功
     */
    public boolean auth(T0102 message){
        String cardNumber = message.getHeader().getMobileNo();
        DeviceInfoVO select = select(cardNumber);
        if (ObjectUtil.isNotNull(select)){
            onlineDeviceInfoMap.put(cardNumber,select);
            return true;
        }
        return false;
    }


    /**
     * 利用心跳延迟在线时间
     * @param cardNumber 卡号
     * @author shuiyun
     * @date 2022/4/23 22:30
     * @return 设备信息
     */
    public DeviceInfoVO heart(String cardNumber){
        return onlineDeviceInfoMap.get(cardNumber);
    }
}
